﻿using Microsoft.EntityFrameworkCore;
using ZhiJiao.Models.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using System.Reflection.Emit;
using Microsoft.AspNetCore.Identity;
using ZhiJiao.Models.Entities;
using ZhiJiao.Models;

namespace ZhiJiao.Dal
{
    public class ZJDbContext : IdentityDbContext<User, Role, string> // 继承：Microsoft.EntityFrameworkCore.DbContext 类
    {
        public ZJDbContext(DbContextOptions<ZJDbContext> options) : base(options)
        {

        }

        /// <summary>
        /// 创建表关系
        /// </summary>
        /// <param name="builder"></param>
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            // 忽略 Identity 表的更改
            //builder.Ignore<IdentityUser>();
            //builder.Ignore<User>();
            //builder.Ignore<Role>();
            //builder.Ignore<Course>();
            //builder.Ignore<IdentityRole>();
            //builder.Ignore<IdentityUserRole<string>>();
            //builder.Ignore<IdentityUserClaim<string>>();
            //builder.Ignore<IdentityUserLogin<string>>();
            //builder.Ignore<IdentityUserToken<string>>();
            //builder.Ignore<IdentityRoleClaim<string>>();

            builder.Entity<Instruction>()
                .HasOne<User>(i => i.ControlUser)
                .WithMany()
                .OnDelete(DeleteBehavior.NoAction);

            // User(多)---> Instruction 
            builder.Entity<User>()
                .HasOne<Instruction>(u => u.Instruction)
                .WithMany();

            builder.Entity<Instruction>()
                .HasMany<Course>(i => i.Courses)
                .WithOne(c=>c.Instruction)
                .HasForeignKey(c=>c.InstructionId)
                .OnDelete(DeleteBehavior.Cascade);

            builder.Entity<Evaluation>()
                .HasOne<Instruction>(e => e.Instruction)
                .WithMany(i => i.Evaluations)
                .OnDelete(DeleteBehavior.NoAction);


            builder.Entity<EvaluationPart>()
                .HasOne<Evaluation>(e => e.Evaluation)
                .WithMany(e => e.EvaluationParts)
                .OnDelete(DeleteBehavior.Cascade);

            builder.Entity<Question>()
                .HasOne<EvaluationPart>(q => q.EvaluationPart)
                .WithMany(e => e.Questions)
                .HasForeignKey(q => q.EvaluationPartId)
                .OnDelete(DeleteBehavior.Cascade);

            // Role （多）----> Instruction
            builder.Entity<Role>()
                .HasOne<Instruction>(r => r.Instruction)
                .WithMany(i => i.Roles)
                .HasForeignKey(r => r.InstructionId)
                .OnDelete(DeleteBehavior.NoAction);

            // Member(多)--->Instruction
            builder.Entity<Member>()
                .HasOne<Instruction>(m => m.Instruction)
                .WithMany()
                .OnDelete(DeleteBehavior.NoAction);

            // Member-->MemberCourse （多）
            builder.Entity<Member>()
                .HasMany<MemberCourse>(m => m.Courses)
                .WithOne(c => c.Member)
                .OnDelete(DeleteBehavior.NoAction);

            // Member -->MemberEvaluation  (多)
            builder.Entity<MemberEvaluation>()
                .HasOne<Member>(me => me.Member)
                .WithMany(m => m.Evaluations)
                .OnDelete(DeleteBehavior.NoAction);

            builder.Entity<MemberEvaluation>()
                .HasOne<Evaluation>(m => m.Evaluation)
                .WithMany()
                .OnDelete(DeleteBehavior.NoAction);

            builder.Entity<MemberEvaluation>()
                .HasOne<Question>(m => m.CurrentQuestion)
                .WithMany()
                .OnDelete(DeleteBehavior.NoAction);

            builder.Entity<MemberEvaluation>()
                .HasOne<Student>(m => m.Student)
                .WithMany(s => s.MemberEvaluations)
                .OnDelete(DeleteBehavior.NoAction);

            builder.Entity<MemberEvaluation>()
                .HasMany<MemberPartResult>(me => me.PartResults)
                .WithOne(mp => mp.MemberEvaluation)
                .OnDelete(DeleteBehavior.NoAction);

            builder.Entity<MemberPartResult>()
                .HasOne<EvaluationPart>(m => m.EvaluationPart)
                .WithMany()
                .OnDelete(DeleteBehavior.NoAction);

            builder.Entity<Module>()
                .HasOne<Module>(m => m.ParentModule)
                .WithMany(p => p.Children)
                .OnDelete(DeleteBehavior.NoAction);

            builder.Entity<Module>()
                .HasMany(m => m.Children)
                .WithOne()
                .OnDelete(DeleteBehavior.NoAction);

            builder.Entity<Student>()
                .HasOne<Member>(s => s.Parent)
                .WithOne(m => m.Student)
                .HasForeignKey<Member>(m => m.Id)
                .OnDelete(DeleteBehavior.NoAction);

            builder.Entity<MemberQuestion>()
                .HasOne<Question>(m => m.Question)
                .WithMany()
                .HasForeignKey(m => m.QuestionId)
                .OnDelete(DeleteBehavior.NoAction);

            // ！！！ 多个导航属性使用一个"外键属性"生成外键约束时，需要"显示声明约束名称"
            builder.Entity<Evaluation>()
                .HasOne<ZJImage>(e => e.MainImage)
                .WithOne()
                .HasForeignKey<ZJImage>(img => img.EvaluationId)
                .OnDelete(DeleteBehavior.Cascade)
                .HasConstraintName("FK_ZJImage_Evaluation_MainImage");

            builder.Entity<Evaluation>()
                .HasOne<ZJImage>(e => e.ListImage)
                .WithOne()
                .HasForeignKey<ZJImage>(img => img.EvaluationId)
                .OnDelete(DeleteBehavior.Cascade)
                .HasConstraintName("FK_ZJImage_Evaluation_ListImage");

            builder.Entity<Evaluation>()
                .HasMany<ZJImage>(e => e.DetailImages)
                .WithOne()
                .HasForeignKey(e => e.EvaluationId)
                .OnDelete(DeleteBehavior.Cascade)
                .HasConstraintName("FK_ZJImage_Evaluation_DetailImages");

            builder.Entity<Question>()
                .HasMany<Option>(e => e.Options)
                .WithOne(o => o.Question)
                .HasForeignKey(o => o.QuestionId)
                .OnDelete(DeleteBehavior.Cascade);

            builder.Entity<Course>()
                .HasMany<CourseImage>(e => e.DetailImages)
                .WithOne()
                .HasForeignKey(img => img.CourseId)
                .OnDelete(DeleteBehavior.Cascade)
                .HasConstraintName("FK_CourseImage_Course_DetailIamges");

            builder.Entity<Course>()
                .HasOne<CourseImage>(c => c.ListImage)
                .WithOne()
                .HasForeignKey<CourseImage>(img => img.CourseId)
                .OnDelete(DeleteBehavior.Cascade)
                .HasConstraintName("FK_CourseImage_Course_ListIamge");

            builder.Entity<Course>()
                .HasOne<CourseImage>(e => e.MainImage)
                .WithOne()
                .HasForeignKey<CourseImage>(img => img.CourseId)
                .OnDelete(DeleteBehavior.Cascade)
                .HasConstraintName("FK_CourseImage_Course_MainImage");

            // 多对多关系

            // MemberQuestion-多对多-Option
            builder.Entity<MemberQuestion>()
               .HasMany(m => m.Result)
               .WithMany(o => o.MemberQuestions)
               .UsingEntity<MemverQuestionOption>(
                   m => m.HasOne<Option>(m => m.Option)
                       .WithMany()
                       .HasForeignKey(m => m.OptionId)
                       .OnDelete(DeleteBehavior.Cascade),
                   m => m.HasOne<MemberQuestion>(m => m.MemberQuestion)
                       .WithMany()
                       .HasForeignKey(m => m.MemberQuestionId)
                       .OnDelete(DeleteBehavior.Cascade)
               );

            // Role-多对多-Module
            builder.Entity<Role>()
                .HasMany(r => r.Modules)
                .WithMany(m => m.Roles)
                .UsingEntity<RoleModule>(
                    j => j
                        .HasOne<Module>(rm => rm.Module)
                        .WithMany(m => m.RoleModules)
                        .HasForeignKey(rm => rm.ModuleId)
                        .OnDelete(DeleteBehavior.Cascade),
                    j => j
                       .HasOne<Role>(rm => rm.Role)
                       .WithMany(r => r.RoleModules)
                       .HasForeignKey(rm => rm.RoleId)
                       .OnDelete(DeleteBehavior.Cascade)
                );


            // Evaluation-多对多-Rule
            builder.Entity<Evaluation>()
                .HasMany(e => e.Rules)
                .WithMany(r => r.Evaluations)
                .UsingEntity<EvaluationRule>(
                    j => j.HasOne<Rule>(j => j.Rule)
                        .WithMany()
                        .HasForeignKey(er => er.RuleId)
                        .OnDelete(DeleteBehavior.Cascade),
                     j => j
                        .HasOne<Evaluation>(e => e.Evaluation)
                        .WithMany()
                        .HasForeignKey(evalRule => evalRule.EvaluationId)
                        .OnDelete(DeleteBehavior.Cascade)
                );

            // Course-多对多-Rule
            builder.Entity<Course>()
                 .HasMany<Rule>(c => c.Rules)
                 .WithMany(r => r.Courses)
                 .UsingEntity<CourseRule>(
                    cr=>cr.HasOne<Rule>(r=>r.Rule)
                        .WithMany()
                        .HasForeignKey(r=>r.RuleId)
                        .OnDelete(DeleteBehavior.NoAction),
                    cr=>cr.HasOne<Course>(r=>r.Course)
                          .WithMany()
                          .HasForeignKey(r=>r.CourseId)
                          .OnDelete(DeleteBehavior.NoAction)
                );

            // 种子数据
            // 超级用户
            builder.Entity<User>()
                .HasData(new User
                {
                    Name = "余冰",
                    NormalizedUserName = "admin",
                    PasswordHash = "AQAAAAEAACcQAAAAEHKZvkwvvBZh9log3FyDMWqnr4WQS2Ft8GiQh1NSWDW46Al3HGvaCmliImFC6vrOfw==",
                    PhoneNumber = "18914894368",
                    UserName = "admin",
                    Type = 0,
                    Instruction = null,
                    Phone = "18914894368",
                    LockoutEnabled = false,
                    PhoneNumberConfirmed = true,
                    AccessFailedCount = 0
                });
        }

        // 把数据表注册为DbContext的属性

        /// <summary>
        /// 测评表
        /// </summary>
        public virtual DbSet<Evaluation> Evaluations { get; set; }

        /// <summary>
        /// 测评模块
        /// </summary>
        public virtual DbSet<EvaluationPart> EvaluationParts { get; set; }

        /// <summary>
        /// 机构表
        /// </summary>
        public virtual DbSet<Instruction> Instructions { get; set; }

        /// <summary>
        /// 会员表
        /// </summary>
        public virtual DbSet<Member> Members { get; set; }

        /// <summary>
        /// 会员测评表
        /// </summary>
        public virtual DbSet<MemberEvaluation> MemberEvaluations { get; set; }

        /// <summary>
        /// 测试题表
        /// </summary>
        public virtual DbSet<Question> Questions { get; set; }

        /// <summary>
        ///  选项
        /// </summary>
        public virtual DbSet<Option> Options { get; set; }

        /// <summary>
        /// 学生表
        /// </summary>
        public virtual DbSet<Student> Students { get; set; }

        /// <summary>
        /// 活动规则表
        /// </summary>
        public virtual DbSet<Rule> Rules { get; set; }

        /// <summary>
        /// 功能模块表
        /// </summary>
        public virtual DbSet<Module> Modules { get; set; }

        /// <summary>
        /// 会员问题答案表
        /// </summary>
        public virtual DbSet<MemberQuestion> MemberQuestions { get; set; }


        public virtual DbSet<RoleModule> RoleModules { get; set; }

        /// <summary>
        /// 测评图片
        /// </summary>
        public virtual DbSet<ZJImage> ZJImages { get; set; }

        /// <summary>
        /// 课程图片
        /// </summary>
        public virtual DbSet<CourseImage> CourseImages { get; set; }

        /// <summary>
        /// 测评参与规则（中间表）
        /// </summary>
        public virtual DbSet<EvaluationRule> EvaluationRules { get; set; }

        /// <summary>
        /// 课程表
        /// </summary>
        public virtual DbSet<Course> Courses { get; set; } 

        /// <summary>
        /// 课程参与规则(中间表)
        /// </summary>
        public virtual DbSet<CourseRule> CourseRules { get; set; }
    }
}
